package frsf.cidisi.exercise.laberinto.search.actions;

import frsf.cidisi.exercise.laberinto.search.EstadoAgente;
import frsf.cidisi.exercise.laberinto.search.EstadoLaberinto;
import frsf.cidisi.exercise.laberinto.search.util.Orientacion;
import frsf.cidisi.exercise.laberinto.search.util.Par;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;
import frsf.cidisi.faia.state.AgentState;
import frsf.cidisi.faia.state.EnvironmentState;

public class Avanzar extends SearchAction {

    /**
     * This method updates a tree node state when the search process is running.
     * It does not updates the real world state.
     */
    @Override
    public SearchBasedAgentState execute(SearchBasedAgentState s) {
    	EstadoAgente agState = (EstadoAgente) s;
    	if(agState.puedeAvanzar()) {
	    	Par pos = agState.getPosicion();
	        Orientacion orient = agState.getOrientacion();
	        Par nuevaPos = pos.sumar(orient.getOrientacion());
	        agState.setPosicion(nuevaPos);
//	        System.out.print(nuevaPos);
//	        if(nuevaPos.equals(new Par(8, 8)))
//	        	System.out.print("----------------------------");
//	        System.out.println(agState.poseeLlave());
	        return agState;
    	}
    	return null;
        
    }

    /**
     * This method updates the agent state and the real world state.
     */
    @Override
    public EnvironmentState execute(AgentState ast, EnvironmentState est) {
        EstadoLaberinto environmentState = (EstadoLaberinto) est;
        EstadoAgente agState = ((EstadoAgente) ast);
        if (agState.puedeAvanzar()) {
	    	Par pos = agState.getPosicion();
	        Orientacion orient = agState.getOrientacion();
	        Par nuevaPos = pos.sumar(orient.getOrientacion());
	        agState.setPosicion(nuevaPos);
	        //environmentState.setPosicion(nuevaPos);
        	
        	// Update the real world            
            // Update the agent state            
            return environmentState;
        }
        return null;
    }

    /**
     * This method returns the action cost.
     */
    @Override
    public Double getCost() {
        return new Double(1);
    }

    /**
     * This method is not important for a search based agent, but is essensial
     * when creating a calculus based one.
     */
    @Override
    public String toString() {
        return "Avanzar";
    }
}